#ifndef JSON_NODE_H
#define JSON_NODE_H

#include <vector>
#include <cstdint>
#include <string>
#include <string_view>
#include <unordered_map>
#include <stdexcept>

#include "./JParserNamespace.h"
#include "JNodeType.h"
#include "JNodeValue.h"

MY_JSON_PARSER_NAMESPACE_BEGIN
class JNode
{
public:
	/* 公有模板构造函数 */
	// 非 bool 且非 double 的整型数值提升为 std::int64_t 进行构造
	template<class T, std::enable_if_t<std::is_integral_v<T> && !std::is_same_v<T, bool> && !std::is_same_v<T, std::int64_t>, int> = 0>
	JNode(T v): JNode(static_cast<std::int64_t>(v))
	{
	}
	// 浮点提升为 double 进行构造
	template<class T, std::enable_if_t<std::is_floating_point_v<T> && !std::is_same_v<T, double>, int> = 0>
	JNode(T v): JNode(static_cast<double>(v))
	{
	}
public:
	/* 公有构造及析构函数 */
	// 默认构造
	JNode();
	// 拷贝构造
	JNode(const myjson::JNode& other);
	// 移动构造
	JNode(myjson::JNode&& other) noexcept;
	// 带参构造
	JNode(const bool& value);
	JNode(const std::int64_t& value);
	JNode(const double& value);
	JNode(const std::string& value);
	JNode(const char* value);
	JNode(const std::vector<myjson::JNode>& value);
	JNode(const std::unordered_map<std::string, myjson::JNode>& value);
	JNode(myjson::JNodeType type);
	// 默认析构
	~JNode();
private:
	/* 私有辅助性函数 */
	// 生成 NULL 类型节点
	void createNull();
	// 生成 Bool 类型节点
	void createBool(const bool& value);
	// 生成 Int 类型节点
	void createInt(const std::int64_t& value);
	// 生成 Double 类型节点
	void createDouble(const double& value);
	// 生成 String 类型节点
	void createString(const std::string& value);
	// 生成 Array 类型节点
	void createArray(const std::vector<myjson::JNode>& value);
	// 生成 Object 类型节点
	void createObject(const std::unordered_map<std::string, myjson::JNode>& value);
	// 根据 JNodeType 生成节点
	void createJNodeWithType(myjson::JNodeType type);
public:
	/* 公有功能性函数 */
	// 清理 node_value 指向的 new 出来的对象 
	void cleanup();
	// 更新 Object 类型的节点的键值对
	void updateObjectKeyValue(const std::string& key, const myjson::JNode& value);
	void updateObjectKeyValue(const std::string& key, myjson::JNode&& value);
	// 删除 Object 类型的节点的某个键
	void deleteObjectKey(const std::string& key);
	// 添加 Array 类型的节点的元素
	void addArrayValue(const myjson::JNode& value);
	void addArrayValue(myjson::JNode&& value);
	// 删除 Array 类型的节点的元素
	void popArrayValue();
	// 转为 JSON 文本
	std::string toJSONText();
	// 转为格式化的 JSON 文本
	std::string toFormatJSONText(const std::uint64_t& indent = 1);
public:
	/* 公有运算符重载模板 */
	template<class T, std::enable_if_t<std::is_integral_v<T> && !std::is_same_v<T, bool> && !std::is_same_v<T, std::int64_t>, int> = 0>
	JNode& operator=(T v)
	{
		return (*this) = static_cast<std::int64_t>(v);
	}
	template<class T, std::enable_if_t<std::is_floating_point_v<T> && !std::is_same_v<T, double>, int> = 0>
	JNode& operator=(T v)
	{
		return (*this) = static_cast<double>(v);
	}
public:
	/* 公有运算符重载 */
	myjson::JNode& operator=(myjson::JNode&& other) noexcept;
	myjson::JNode& operator=(const myjson::JNode& other);
	myjson::JNode& operator=(std::nullptr_t);
	myjson::JNode& operator=(const bool& check);
	myjson::JNode& operator=(const std::int64_t& num);
	myjson::JNode& operator=(const double& num);
	myjson::JNode& operator=(const std::string& str);
	myjson::JNode& operator=(const char* str);
	myjson::JNode& operator=(char* str);
	myjson::JNode& operator=(const std::vector<myjson::JNode>& arr);
	myjson::JNode& operator=(const std::unordered_map<std::string, myjson::JNode>& obj);
	myjson::JNode& operator[](const std::string& key);
	myjson::JNode& operator[](const std::uint64_t& index);
private:
	/* 私有成员变量 */
	// JSON 节点类型
	myjson::JNodeType node_type;
	// JSON 节点值
	myjson::JNodeValue node_value;
};
MY_JSON_PARSER_NAMESPACE_END

#endif // !JSON_NODE_H
